package org.cloudie.docs.editor.client.content.dialogs;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

import java.util.ArrayList;

import org.cloudie.docs.editor.client.commands.generic.ExistingDocumentLoadCommand;
import org.cloudie.docs.editor.client.commands.generic.NewDocumentLoadCommand;
import org.cloudie.docs.editor.client.commands.generic.SplashDialogListDesktopsCommand;
import org.cloudie.docs.editor.client.events.CommandEvent;
import org.cloudie.docs.editor.client.events.DoubleClickHandler;
import org.cloudie.docs.editor.client.feeds.docs.FileServiceEntry;
import org.cloudie.docs.editor.client.resources.icons.IconsHelper;
import org.cloudie.docs.editor.client.widgets.Dialog;

/**
 * A dialog window displaying a splash screen with options to select the desktop to edit.
 */
public class SplashDialog extends Dialog {

  protected static SplashDialog instance;
  
  public static SplashDialog get() {
    if (instance == null) {
      instance = new SplashDialog();
    }
    return instance;
  }

  private ArrayList<SelectorEntry> entries;
  private VerticalPanel selector;
  private ScrollPanel scroller;
  
  /**
   * Constructs a Splash dialog window.
   */
  protected SplashDialog() {
    super("Cloudie", true);
    entries = new ArrayList<SelectorEntry>();
    closeButton.setVisible(false);
    VerticalPanel content = new VerticalPanel();
    content.setStylePrimaryName("cloudie-Splash");
    Image logo = IconsHelper.icons.CloudieLogo().createImage();
    logo.setStylePrimaryName("cloudie-Splash-Logo");
    CheckBox isReadOnly = new CheckBox("Open desktop in read-only mode (changes are not saved).");
    Button openButton = new Button("Open Selected Desktop");
    openButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        choose();
      }
    });
    selector = new VerticalPanel();
    selector.setStylePrimaryName("cloudie-Splash-Selector-Grid");
    selector.setWidth("100%");
    scroller = new ScrollPanel(selector);
    scroller.setStylePrimaryName("cloudie-Splash-Selector");
    scroller.setSize("100%", "100px");
    VerticalPanel leftAligned = new VerticalPanel();
    leftAligned.setWidth("100%");
    leftAligned.setHorizontalAlignment(VerticalPanel.ALIGN_LEFT);
    leftAligned.add(new Label("Select a desktop:"));
    leftAligned.add(scroller);
    leftAligned.add(isReadOnly);
    leftAligned.add(openButton);
    content.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
    content.add(logo);
    content.add(new HTML("<span style=\"font-weight:bold;color:green;\">Proof Of Concept</span>"));
    content.add(leftAligned);
    content.add(new Label("Cloudie Desktop 1.0 Beta"));
    setDesktops(new FileServiceEntry[0]);
    setContentWidget(content);
  }
  
  private void refresh() {
    selector.clear();
    for (SelectorEntry entry : entries) {
      selector.add(entry);
    }
  }
  
  public void setDesktops(FileServiceEntry[] desktops) {
    entries.clear();
    entries.add(new SelectorEntry("New Desktop...", null, true));
    for (FileServiceEntry desktop : desktops) {
      entries.add(new SelectorEntry(desktop.getTitle(),
          desktop.getDocumentId()));
    }
    refresh();
  }
  
  @Override
  public void show() {
    super.show();
    CommandEvent.fire(new SplashDialogListDesktopsCommand());
  }
  
  private void setSelection(SelectorEntry selected) {
    for (SelectorEntry entry : entries) {
      entry.setSelected(false);
    }
    selected.setSelected(true);
  }
  
  private void choose() {
    for (SelectorEntry entry : entries) {
      if (entry.selected) {
        choose(entry);
        break;
      }
    }
  }
  
  private void choose(SelectorEntry chosen) {
    hide();
    if (chosen.value == null) {
      CommandEvent.fire(new NewDocumentLoadCommand());
    } else {
      CommandEvent.fire(new ExistingDocumentLoadCommand(chosen.value));
    }
  }
  
  private class SelectorEntry extends FocusPanel {
    
    private String value;
    private boolean selected = false;
    
    public SelectorEntry(final String label, String value) {
      this(label, value, false);
    }
    
    public SelectorEntry(String label, String value, boolean selected) {
      super();
      this.value = value;
      this.setWidth("100%");
      this.setStylePrimaryName("cloudie-Splash-Selector-Grid-Entry");
      HorizontalPanel entryPanel = new HorizontalPanel();
      entryPanel.add(IconsHelper.icons.Document().createImage());
      entryPanel.add(new Label(label));
      this.add(entryPanel);
      this.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
          setSelection(SelectorEntry.this);
        }
      });
      this.addClickHandler(new DoubleClickHandler() {
        @Override
        public void onDoubleClick(ClickEvent event) {
          choose(SelectorEntry.this);
        }
      });
      this.setSelected(selected);
    }
    
    public void setSelected(boolean selected) {
      this.selected = selected;
      if (selected) {
        setStylePrimaryName("cloudie-Splash-Selector-Grid-Entry-Selected");
      } else {
        setStylePrimaryName("cloudie-Splash-Selector-Grid-Entry");
      }
    }
    
  }
}
